package com.yunwaikeji.gy_tool_library.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewTreeObserver;

import com.yunwaikeji.gy_tool_library.R;
import com.yunwaikeji.gy_tool_library.info.GYFlexboxLayoutInfo;
import com.yunwaikeji.gy_tool_library.interface1.GYViewBgInterface;
import com.yunwaikeji.gy_tool_library.interface1.GYViewGroupInterface;
import com.yunwaikeji.gy_tool_library.interface1.OnItemClickListener;
import com.yunwaikeji.gy_tool_library.set.GYViewBgBuilder;
import com.yunwaikeji.gy_tool_library.set.GYViewGroupSetSet;
import com.yunwaikeji.gy_tool_library.utils.display.GYDisplayUtils;
import com.yunwaikeji.gy_tool_library.utils.GYViewUtils;
import com.yunwaikeji.gy_tool_library.widget.flexboxLayout.FlexWrap;
import com.yunwaikeji.gy_tool_library.widget.flexboxLayout.FlexboxLayout;

import java.util.ArrayList;
import java.util.List;

public class GYFlexboxLayout extends FlexboxLayout implements GYViewBgInterface<GYFlexboxLayout, GYFlexboxLayout.GYViewBgBuilder1>, GYViewGroupInterface<GYFlexboxLayout, GYFlexboxLayout.GYViewSet>, GYFlexboxLayoutInfo {

    public GYFlexboxLayout(Context context) {
        super(context);
        initView(null);
    }

    public GYFlexboxLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(attrs);
    }

    public GYFlexboxLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(attrs);
    }

    private List<List<View>> viewListList = new ArrayList<>();

    private GYViewBgBuilder1 viewBgBuilder1;

    @Override
    public GYViewBgBuilder1 getBackgroundBuilder() {
        return getBackgroundBuilder(null);
    }

    @Override
    public GYViewBgBuilder1 getBackgroundBuilder(AttributeSet attributeSet) {
        if (viewBgBuilder1 == null) {
            viewBgBuilder1 = new GYViewBgBuilder1(this, attributeSet);
        }
        return viewBgBuilder1;
    }

    private GYViewSet viewSet;

    @Override
    public GYViewSet getViewSet() {
        if (viewSet == null) {
            viewSet = new GYViewSet(this);
        }
        return viewSet;
    }

    public static class GYViewBgBuilder1 extends GYViewBgBuilder<GYFlexboxLayout, GYViewBgBuilder1> {
        public GYViewBgBuilder1(View view, AttributeSet attributeSet) {
            super(view, attributeSet);
        }

        public GYViewBgBuilder1(View view) {
            super(view);
        }
    }

    public class GYViewSet extends GYViewGroupSetSet<GYFlexboxLayout, GYViewSet> {
        private int spacingHorizontalPx = 0;
        private int spacingVerticalPx = 0;
        private int maxLineCount = 0;//每行最大item数量

        public GYViewSet(View view) {
            super(view);
        }

        public GYViewSet setMaxLineCount(int maxLineCount) {
            this.maxLineCount = maxLineCount;
            refreshView();
            return this;
        }

        /**
         * 获取横向间距
         *
         * @return
         */
        public float getSpacingHorizontalPx() {
            return spacingHorizontalPx;
        }

        /**
         * 设置横向间距
         *
         * @return
         */
        public GYViewSet setSpacingHorizontalDp(int spacingHorizontalDp) {
            return setSpacingHorizontalPx(GYDisplayUtils.dp2px(getContext(), spacingHorizontalDp));
        }

        public GYViewSet setSpacingHorizontalPx(int spacingHorizontalPx) {
            this.spacingHorizontalPx = spacingHorizontalPx;
            refreshView();
            return this;
        }

        /**
         * 获取纵向间距
         *
         * @return
         */
        public float getSpacingVerticalPx() {
            return spacingVerticalPx;
        }

        /**
         * 设置纵向间距
         *
         * @param spacingVerticalDp
         * @return
         */
        public GYViewSet setSpacingVerticalDp(int spacingVerticalDp) {
            return setSpacingVerticalPx(GYDisplayUtils.dp2px(getContext(), spacingVerticalDp));
        }

        /**
         * 设置纵向间距
         *
         * @param spacingVertical
         * @return
         */
        public GYViewSet setSpacingVerticalPx(int spacingVertical) {
            this.spacingVerticalPx = spacingVertical;
            refreshView();
            return this;
        }

        private OnItemClickListener onItemClickListener;

        public GYViewSet setOnItemClickListener(OnItemClickListener onItemClickListener) {
            this.onItemClickListener = onItemClickListener;
            return this;
        }

        public GYViewSet setMultiline(boolean multiline) {
            isMultiline = multiline;
            if (!isMultiline) {
                setFlexWrap(FlexWrap.NOWRAP);
            } else {
                if (getFlexWrap() == FlexWrap.WRAP_REVERSE) {
                    setFlexWrap(FlexWrap.WRAP_REVERSE);
                } else {
                    setFlexWrap(FlexWrap.WRAP);
                }
            }
            return this;
        }

        public boolean isMultiline() {
            return isMultiline;
        }

        public List<List<View>> getViewListList(){
            return viewListList;
        }
    }

    private boolean isMultiline = true;

    public void initView(AttributeSet attributeSet) {
        getBackgroundBuilder(attributeSet).build();
        if (attributeSet != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.GYFlexboxLayout);
            getViewSet().spacingHorizontalPx = typedArray.getDimensionPixelSize(R.styleable.GYFlexboxLayout_spacingHorizontal, getViewSet().spacingHorizontalPx);
            getViewSet().spacingVerticalPx = typedArray.getDimensionPixelSize(R.styleable.GYFlexboxLayout_spacingVertical, getViewSet().spacingVerticalPx);
            isMultiline = typedArray.getBoolean(R.styleable.GYFlexboxLayout_isMultiline, isMultiline);
        }
        getViewSet().setMultiline(isMultiline);

        refreshView();

        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
            }
        });
    }

    @Override
    public GYViewBgBuilder1 setBackgroundBuilder(GYViewBgBuilder1 gyViewBgBuilder1) {
        viewBgBuilder1 = gyViewBgBuilder1;
        return viewBgBuilder1;
    }

    public void refreshView() {
        isRefresh = true;
        requestLayout();
        invalidate();
    }

    private boolean isRefresh = true;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isRefresh) {
            isRefresh = false;
            viewListList.clear();
            List<View> rowViewList = new ArrayList<>();
            for (int i = 0; i < getViewSet().getChildViews().size(); i++) {
                View view = getViewSet().getChildViews().get(i);
                int finalI = i;
                view.setOnClickListener(v -> {
                    if (getViewSet().onItemClickListener != null) {
                        getViewSet().onItemClickListener.onItemClick(view, finalI);
                    }
                });
                if (isMultiline) {
                    if (rowViewList.size() == 0) {
                        rowViewList.add(view);
                        if (getWidth(rowViewList) >= getWidth()) {
                            viewListList.add(rowViewList);
                            rowViewList = new ArrayList<>();
                        }
                    } else {
                        float viewWidth = getWidth(rowViewList) + getViewSet().spacingHorizontalPx * rowViewList.size() + view.getWidth();
                        if (viewWidth < getWidth()) {
                            rowViewList.add(view);
                            if (rowViewList.size() >= getViewSet().maxLineCount && getViewSet().maxLineCount > 0) {
                                View view1 = rowViewList.get(rowViewList.size() - 1);
                                LayoutParams layoutParams = (LayoutParams) view1.getLayoutParams();
                                GYViewUtils.setMargin().setMarginPx(view1, layoutParams.leftMargin, 0, (int) (layoutParams.rightMargin + (getWidth() - viewWidth)), 0);
                                viewListList.add(rowViewList);
                                rowViewList = new ArrayList<>();
                            }
                        } else if (viewWidth == getWidth()) {
                            rowViewList.add(view);
                            viewListList.add(rowViewList);
                            rowViewList = new ArrayList<>();
                        } else {
                            viewListList.add(rowViewList);
                            rowViewList = new ArrayList<>();
                            rowViewList.add(view);
                            if (view.getWidth() >= getWidth()) {
                                viewListList.add(rowViewList);
                                rowViewList = new ArrayList<>();
                            }
                        }
                    }
                } else {
                    rowViewList.add(view);
                }
            }
            if (rowViewList.size() > 0) {
                viewListList.add(rowViewList);
            }
            for (int i = 0; i < viewListList.size(); i++) {
                List<View> viewList = viewListList.get(i);
                for (int j = 0; j < viewList.size(); j++) {
                    View view = viewList.get(j);
                    int marginLeft = 0;
                    int marginTop = 0;
                    LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
                    int marginRight = layoutParams.getMarginRight();
                    if (i > 0) {
                        marginTop = getViewSet().spacingVerticalPx;
                    }
                    if (isMultiline) {
                        if (j > 0) {
                            marginLeft = getViewSet().spacingHorizontalPx + layoutParams.leftMargin;
                            if (j == viewList.size() - 1) {
                                marginRight += getWidth() - (getWidth(viewList) + getViewSet().spacingHorizontalPx * (viewList.size() - 1));
                            }
                        }
                    } else {
                        int spanCount = viewList.size();
                        int allPx = getViewSet().spacingHorizontalPx * (spanCount - 1);
                        int item = allPx / spanCount;
                        if (j == 0) {
                            marginRight += item;
                        } else if (j == spanCount - 1) {
                            marginLeft += item;
                        } else {
                            marginLeft += (getViewSet().spacingHorizontalPx - item);
                            marginRight += (item - (getViewSet().spacingHorizontalPx - item));
                        }
                    }
                    layoutParams.setMargins(marginLeft, marginTop, marginRight, 0);
                    view.setLayoutParams(layoutParams);
                    super.drawChild(canvas, view, getDrawingTime());
                }
            }
        }
    }

    private int getWidth(List<View> viewList) {
        int width = 0;
        for (View view : viewList) {
            width += view.getWidth();
            LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
            width += layoutParams.leftMargin;
            width += layoutParams.rightMargin;
        }
        return width;
    }
}
